package com.coincalf.framework.utils;

import lombok.extern.slf4j.Slf4j;
import org.bitcoinj.core.Address;
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.params.MainNetParams;
import org.bouncycastle.util.encoders.Hex;
import org.springframework.util.StringUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class AddressUtil {

    //ETH系列地址格式校验
    public static boolean verifyEthAddress(String address) {
        if (address.startsWith("0x")) {
            String regex = "^[0-9a-fA-F]{40}$";
            Pattern compile = Pattern.compile(regex);
            Matcher matcher = compile.matcher(address.substring(2));
            return matcher.find();
        } else {
            return false;
        }
    }

    //BTC系列地址格式校验
    public static boolean verifyBtcAddress(String address) {
        try {
            NetworkParameters networkParameters = MainNetParams.get();
            Address.fromString(networkParameters, address);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    //TRX系列地址格式校验
    public static boolean verifyTrxAddress(String address) {
        if (!address.startsWith("T")) {
            return false;
        }
        try {
            byte[] decodeCheck = org.tron.common.utils.Base58.decode(address);
            if (decodeCheck.length <= 4) {
                throw new RuntimeException("地址格式转换异常");
            }
            byte[] decodeData = new byte[decodeCheck.length - 4];
            System.arraycopy(decodeCheck, 0, decodeData, 0, decodeData.length);
            byte[] hash0 = Sha256Sm3Hash.hash(decodeData);
            byte[] hash1 = Sha256Sm3Hash.hash(hash0);
            if (hash1[0] == decodeCheck[decodeData.length]
                    && hash1[1] == decodeCheck[decodeData.length + 1]
                    && hash1[2] == decodeCheck[decodeData.length + 2]
                    && hash1[3] == decodeCheck[decodeData.length + 3]) {
                Hex.toHexString(decodeData);
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            return false;
        }
    }

    public static boolean verifyAddress(Long coinId, String address) {
        if (coinId == null || StringUtils.isEmpty(address)) {
            return false;
        }
        if (coinId == 1 || coinId == 2) {
            return AddressUtil.verifyBtcAddress(address);
        } else if (coinId == 3 || coinId == 4 || coinId == 11) {
            return AddressUtil.verifyEthAddress(address);
        } else if (coinId == 5 || coinId == 6) {
            return AddressUtil.verifyTrxAddress(address);
        } else {
            log.warn("暂不支持该币种地址校验 coinId={} address={}", coinId, address);
            return false;
        }
    }

}
